package datastructure;

import java.util.Iterator;
import java.util.Objects;

public class SqListClass<E> implements Iterable<E> {
    E[] data;
    private int size;
    private final static int INIT_CAPACITY = 10;

    public SqListClass() {
        data = (E[]) new Object[INIT_CAPACITY];
    }

    public SqListClass(int capacity) {
        data = (E[]) new Object[capacity];
    }

    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer("[" + (size > 0 ? data[0] : ""));
        for (int i = 1; i < size; i++)
            stringBuffer.append(" ," + data[i]);
        stringBuffer.append("]");
        return stringBuffer.toString();
    }

    public void updateCapacity(int capacity) {
        E[] newData = (E[]) new Object[capacity];
        for (int i = 0; i < size; i++)
            newData[i] = data[i];
        data = newData;
    }

    public void createList(E[] e) {
        size = 0;
        for (int i = 0; i < e.length; i++) {
            if (size >= data.length)
                updateCapacity(2 * size);
            data[size++] = e[i];
        }
    }

    public boolean createNoRepeatList(E[] e) {
        for (int i = 0; i < e.length - 1; i++)
            for (int j = i + 1; j < e.length; j++)
                if (Objects.equals(e[i], e[j]))
                    return false;
        createList(e);
        return true;
    }

    public void add(E e) {
        if (size >= data.length)
            updateCapacity(2 * size);
        data[size++] = e;
    }

    public boolean addNoRepeat(E e) {
        for (int i = 0; i < size; i++)
            if (Objects.equals(data[i], e))
                return false;
        add(e);
        return true;
    }

    public int getSize() {
        return size;
    }

    public E getElement(int index) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("SqListClass.getElement中参数index不合法！");
        else
            return data[index];
    }

    public void setElement(int index, E e) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("SqListClass.getElement中参数index不合法！");
        else
            data[index] = e;
    }

    public int getIndex(E e) {
        int temp = 0;
        while (temp < size && !Objects.equals(e, data[temp++])) ;
        return temp < size ? temp : -1;
    }

    public void swap(int index1, int index2) {
        E temp = data[index1];
        data[index1] = data[index2];
        data[index2] = temp;
    }

    public void insert(int index, E e) {
        if (index < 0 || index > size)
            throw new IllegalArgumentException("SqListClass.insert中参数index不合法！");
        else {
            if (size >= data.length)
                updateCapacity(2 * size);
            for (int i = size; i > index; i--)
                data[i] = data[i - 1];
            data[index] = e;
            size++;
        }
    }

    public boolean insertNoRepeat(int index, E e) {
        for (int i = 0; i < size; i++)
            if (Objects.equals(data[i], e))
                return false;
        insert(index, e);
        return true;
    }

    public void delete(int index) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("SqListClass.delete中参数index不合法！");
        else {
            for (int i = index; i < size - 1; i++)
                data[i] = data[i + 1];
            data[--size] = null;
            if (data.length > INIT_CAPACITY && size <= data.length / 4)
                updateCapacity(data.length / 2);
        }
    }

    public void delete(E e) {
        delete(getIndex(e));
    }

    public boolean isEmpty(){
        return size==0;
    }

    @Override
    public Iterator<E> iterator() {
        return new SqListClassIterator<>(this);
    }

    private class SqListClassIterator<E> implements Iterator<E> {
        private SqListClass list;
        int current;

        public SqListClassIterator(SqListClass list) {
            this.list = list;
        }

        @Override
        public boolean hasNext() {
            return current < list.getSize();
        }

        @Override
        public E next() {
            return (E) list.getElement(current++);
        }
    }
}
